<!--
 * @Author: 330GRX 617947173@qq.com
 * @Date: 2023-09-28 20:37:54
 * @LastEditors: 330GRX 617947173@qq.com
 * @LastEditTime: 2023-10-02 12:14:09
 * @FilePath: \Realtime-Chat\web\src\components\MessageList.vue
 * @Description: 
 * 
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved. 
-->
<template>
  <div class="messagelist-container" ref="scrollRef">
    <div v-for="message in messages" :class="`message ${message.fromSelf ? 'sended' : 'received'}`">
      <div class="content">
        <p>{{ message.message }}</p>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, watchEffect, onBeforeUnmount, nextTick } from 'vue'
import { useCurrentChatStore, useCurrentUserStore } from '@/stores/index'
import { getAllMessageRoute } from '@/utils/APIRoutes'
import axios from 'axios'

// 当前会话的用户
const currentChatStore = useCurrentChatStore()
// 当前用户
const currentUserStore = useCurrentUserStore()
// 消息列表
const messages = ref([])
// 接收父组件传递过来的socket对象
const props = defineProps({
  socket: Object
})
// 滚动条ref
let scrollRef = ref(null)

// watchEffect 也是一个帧听器，是一个副作用函数。
// 它会监听引用数据类型的所有属性，不需要具体到某个属性，一旦运行就会立即监听，组件卸载的时候会停止监听。
// 这里监听到currentChatStore.currentChat改变
const stopChat = watchEffect(async () => {
  // 获取所有信息
  const { data } = await axios.post(getAllMessageRoute, {
    from: currentUserStore.currentUser._id,
    to: currentChatStore.currentChat._id
  })
  messages.value = data

  // 滚动条自动滚动到最下方
  setTimeout(() => {
    scrollRef.value.scrollTop = scrollRef.value.scrollHeight
  }, 10)
}, [currentChatStore.currentChat])
const stopProps = watchEffect(() => {
  if (props) {
    // console.log(props)
  }
}, [props])
onBeforeUnmount(() => {
  // 停止监听
  stopChat()
  stopProps()
})

/**
 * @description: 处理发送信息
 * @param {String} msg 要发送的信息
 */
const handleSendMsg = (msg) => {
  const msgs = [...messages.value]
  msgs.push({ fromSelf: true, message: msg })
  messages.value = msgs

  // 滚动条自动滚动到最下方
  nextTick(() => {
    scrollRef.value.scrollTop = scrollRef.value.scrollHeight
  })
}
/**
 * @description: 处理接收信息
 * @param {String} arrivalMsg 收到的信息
 */
const handleReceiveMsg = (arrivalMsg) => {
  messages.value.push(arrivalMsg)

  // 滚动条自动滚动到最下方
  nextTick(() => {
    scrollRef.value.scrollTop = scrollRef.value.scrollHeight
  })
}
// 向外暴露的函数
defineExpose({ handleSendMsg, handleReceiveMsg })
</script>

<style lang="scss" scoped>
.messagelist-container {
  height: 95%;
  padding: 1rem 2rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  overflow: auto;
  .message {
    display: flex;
    align-items: center;
    .content {
      max-width: 40%;
      overflow-wrap: break-word;
      padding: 1rem;
      font-size: 1.1rem;
      border-radius: 1rem;
      color: #d1d1d1;
    }
  }
  .sended {
    justify-content: flex-end;
    .content {
      background-color: #4f04ff21;
    }
  }
  .received {
    justify-content: flex-start;
    .content {
      background-color: #9900ff20;
    }
  }
}
</style>
